package com.xbhog.session.defaults;

import com.xbhog.mapping.Environment;
import com.xbhog.mapping.MappedStatement;
import com.xbhog.session.Configuration;
import com.xbhog.session.SqlSession;

import javax.sql.DataSource;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author xbhog
 * @describe:
 * @date 2024/2/25
 */
public class DefaultSqlSession implements SqlSession {
    private Configuration configuration;

    public DefaultSqlSession(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    public <T> T  selectOne(String statement,Object parameter) throws SQLException, ClassNotFoundException {
        MappedStatement mappedStatements = configuration.getMappedStatements(statement);
        Environment environment = configuration.getEnvironment();
        Connection connection = environment.getDataSource().getConnection();
        String sql = mappedStatements.getSql();
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        preparedStatement.setLong(1,Long.parseLong(((Object[]) parameter)[0].toString()));
        ResultSet resultSet = preparedStatement.executeQuery();
        //对数据库结果数据进行清洗;入参jdbc执行结果以及结果类型(对应于SQL查询结果映射到的Java类型的全限定名-User)
        List<T> resultSet2Obj = resultSet2Obj(resultSet, Class.forName(mappedStatements.getResultType()));
        return resultSet2Obj.get(0);
    }
    private <T> List<T> resultSet2Obj(ResultSet resultSet, Class<?> clazz) {
        List<T> list = new ArrayList<>();
        try {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            // 每次遍历行值
            while (resultSet.next()) {
                T obj = (T) clazz.newInstance();
                for (int i = 1; i <= columnCount; i++) {
                    Object value = resultSet.getObject(i);
                    String columnName = metaData.getColumnName(i);
                    //属性首字母大写
                    String setMethod = "set" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
                    Method method;
                    if (value instanceof Timestamp) {
                        method = clazz.getMethod(setMethod, Date.class);
                    } else {
                        //会寻找clazz类(User)中名字为setMethod（setId），并且只接受一个参数的方法，且该参数类型与value.getClass()所返回的类型一致
                        method = clazz.getMethod(setMethod, value.getClass());
                    }
                    //实体类属性赋值
                    method.invoke(obj, value);
                }
                list.add(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    @Override
    public <T> T getMapper(Class<T> type) {
        return configuration.getMapper(type,this);
    }

    @Override
    public Configuration getConfiguration() {
        return configuration;
    }
}
